package client.netty;

import client.TankClient;
import code.GpcDataServerEncoder;
import code.GpcDecoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import newtank.data.AbstractDataPackage;
import newtank.data.EnvironmentInitSignal;

/**
 * 网络连接器
 * @author lijiahao
 */
public class NetWorkClient {

	private final String host;
	
	private final int port;

    /**
     * 客户端版本码
     */
	private String md5_client_version;
	
	private Channel channel;
	
	private NetWorkClient(String ip, int port) {
		this.host = ip;
		this.port = port;
	}
	
	public static NetWorkClient builder(String ip, int port) {
		return new NetWorkClient(ip, port);
	}
	
	public void start(TankClient client) throws InterruptedException {
		final EventLoopGroup group = new NioEventLoopGroup();
		 
        Bootstrap b = new Bootstrap();
        // 使用NioSocketChannel来作为连接用的channel类
		// 绑定连接初始化器
        b.group(group).channel(NioSocketChannel.class)
            .handler(new ChannelInitializer<SocketChannel>() {
                @Override
                public void initChannel(SocketChannel ch) {
                    ChannelPipeline pipeline = ch.pipeline();
                    pipeline.addLast(new GpcDataServerEncoder()); //编码request
                    pipeline.addLast(new GpcDecoder()); //解码response
                    pipeline.addLast(new ClientDataHandler(client)); //客户端处理类
                }
            });
        //发起异步连接请求，绑定连接端口和host信息
        final ChannelFuture future = b.connect(host, port).sync();
 
        future.addListener((ChannelFutureListener) arg0 -> {
            if (future.isSuccess()) {
                sendMessage(new EnvironmentInitSignal());
            } else {
                future.cause().printStackTrace();
                group.shutdownGracefully(); //关闭线程组
            }
        });
 
        this.channel = future.channel();
	}
	
	public void sendMessage(AbstractDataPackage message) {
		if(message.getContext() != null) {
			message.setLength(String.valueOf(message.getContext()).getBytes().length);
		}
        System.out.println("发送数据包：" + message);
		channel.writeAndFlush(message);
	}
	
	public void close() {
		channel.close();
	}

}
